<template>
  <div class="t-gen-form">
    <el-row :gutter="formConfCopy.gutter">
      <el-form
        :ref="formConfCopy.formRef"
        :disabled="formConf.disabled"
        :label-position="formConfCopy.labelPosition"
        :label-width="formConfCopy.labelWidth + 'px'"
        :model="formModel"
        :rules="formRules"
        :size="formConfCopy.size"
      >
        <generate-form-item
          v-for="(item, index) in formConfCopy.fields"
          :key="`${item.key}_${index}`"
          :ref="item.vModel"
          :cid="item.vModel"
          :index="index"
          :item="item"
          :seqNo="seqNos[index]"
          :models.sync="formModel"
          :rules="formRules"
          :style="isFieldShow(item)"
          @next="nextPage"
          @prev="prevPage"
          @input-change="onInputChange"
          @ocr-success="handleOcrSuccess"
        />
        <el-col v-if="formConfCopy.formBtns">
          <el-form-item
            class="submit-btn-form-item"
            size="large"
            style="margin-top: 30px"
          >
            <el-button
              v-if="showSubmitBtn"
              type="primary"
              :loading="btnLoading"
              @click="beforeSubmitForm"
            >
              {{
                formConfCopy.theme && formConfCopy.theme.submitBtnText
                  ? formConfCopy.theme.submitBtnText
                  : "提交"
              }}
            </el-button>
            <el-button v-if="formConfCopy.resetBtn" @click="resetForm">
              重置
            </el-button>
          </el-form-item>
        </el-col>
      </el-form>
    </el-row>
    <el-dialog
      title="提示"
      append-to-body
      :visible.sync="dialogVisible"
      @close="handleDialogClose"
      width="30%">
      <span>提交后不能修改，请谨慎提交</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleDialogClose">取 消</el-button>
        <el-button type="primary" @click="submitForm">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
import { handleChangeLabel } from "./FormItemLabel";
import _ from "lodash";
import "../FormItem/autoRegister.js";
import { evalExpression } from "../../utils/expression";
import { execRemoteAPI } from "../../api/execRemoteAPI";
import GenerateFormItem from "./GenerateFormItem";
import { throttle } from "throttle-debounce";
import FormValidateRule from "./FormValidateRule";
import { saveFormData } from "../../utils/db";
import { formatDate } from "../../../../utils/formatTime";
let seqNo = 0;

export default {
  name: "GenerateForm",
  components: {
    GenerateFormItem,
  },
  mixins: [FormValidateRule],
  props: {
    formConf: {
      type: Object,
      required: true,
    },
    // 被触发了逻辑显示的字段列表
    logicTriggerItemList: {
      type: Array,
      required: false,
    },
    pageFormModel: {
      type: Object,
      required: false,
    },
  },
  data() {
    return {
      // 维护一个对象存储 字段名和字段的index 避免查找
      fieldIdIndex: {},
      formConfCopy: _.cloneDeep(this.formConf),
      formModel: _.cloneDeep(this.pageFormModel),
      formRules: {},
      btnLoading: false,
      date:'',
      dialogVisible:false,
      formConfCopyFields: [],
      seqNos: []
    };
  },
  watch: {
    'formConfCopy.fields': {
      handler() {
        let num = 0
        this.seqNos = this.formConfCopy.fields.map(item => {
          if (!this.formConfCopy.theme || this.formConfCopy.theme.showNumber !== true) {
            return '';
          }
          item.seqNo = ''
          if (!this.isFieldShow2(item) && item.displayType == false) {
            if (item.typeId != 'DIVIDER' && item.typeId != 'PAGINATION'  && item.typeId != 'RANDOM_NUMBER' && item.typeId != 'SLIDER') {
              num++
              item.seqNo = num
            }
          }
          return num
        })
      },
      deep: true,
      immediate: true
    },
  },
  computed: {
    showSubmitBtn() {
      if (!this.formConfCopy.theme) {
        return true;
      }
      if (
        this.formConfCopy.theme &&
        false == this.formConfCopy.theme.showSubmitBtn
      ) {
        return false;
      }
      return true;
    },
  },
  created() {

    this.accessTime= new Date()
    // 初始化动态数据 比如SELECT等远程数据
    this.initDynamicOptions(this.formConfCopy.fields);
    // 初始化默认值
    this.initFormData(this.formConfCopy.fields, this.formModel);


  },
  mounted() {
    console.log(this.logicTriggerItemList,'this.logicTriggerItemList111')
    this.buildRules(this.formConfCopy.fields, this.formRules);
    // 有些组件是非必填，但是绑定得逻辑组件是必填，但不会主动去触发，这个时候要去除掉被绑的
    this.logicShowHandle2()
    // 特殊处理分页
    seqNo = this.formConfCopy.startSeqNo || 0;
    // console.log(this.formRules, this.formModel, '-- this.formRules, this.formModel --')

  },
  methods: {
    getKey() {
      return new Date();
    },
    // 初始化问卷动态选项
    async initDynamicOptions(componentList) {
      for (const cur of componentList) {
        const config = cur.config;
        // 数据为从接口获取
        if (config.optionsType && config.optionsType === 1) {
          execRemoteAPI.get(config.dynamicOptions.url).then((res) => {
            const options = _.get(res.data, config.dynamicOptions.dataPath);
            if (options && _.isArray(options)) {
              const dyOptions = options.map((op) => ({
                value: _.get(op, config.dynamicOptions.valueField),
                label: _.get(op, config.dynamicOptions.labelField),
              }));
              config.options = dyOptions;
            }
          });
        }
        // 从字典获取
        if (config.optionsType && config.optionsType === 2) {
          let dictRes = await execRemoteAPI.get(
            `/system/dict/data/type/${config.dictOptionType}`
          );
          config.options = dictRes.data.data.map((op) => ({
            value: op.dictValue,
            label: op.dictLabel,
          }));
        }
      }
    },
    // 初始化问卷默认值
    initFormData(componentList, formData) {
      // 设置默认值
      componentList.forEach((cur, index) => {
        const config = cur.config;
        this.fieldIdIndex[cur.vModel] = index;
        // 如果存在分页带回的数据 则不再设置默认 0是checkbx radio等的其他输入框
        if (cur.vModel && !formData[cur.vModel] && 0 != formData[cur.vModel]) {
          formData[cur.vModel] = config.defaultValue;
          handleChangeLabel(formData, cur, config.defaultValue);
        }
        if (config.children) this.initFormData(config.children, formData);
      });
    },

    removeRule(cur) {
      delete this.formRules[cur.vModel];
    },
    resetForm() {
      this.formConfCopy = _.cloneDeep(this.formConf);
      this.$refs[this.formConf.formRef].resetFields();
    },
    // 问卷校验规则
    buildRules(componentList, rules) {
      componentList.forEach((cur) => {
        // 逻辑不显示必填问题不校验
        const triggerShow =
          _.indexOf(this.logicTriggerItemList, cur.formItemId) > -1;
        // cur.logicShow 是否逻辑显示字段  triggerShow 已经被触发显示的问题
        // 是逻辑显示字段  并且还没满足条件被显示·
        if (cur.logicShowField !== true || triggerShow) {
          if(cur.typeId == "MATRIX_TABLE"){
            this.$refs[cur.vModel][0].aaa()
          }

          this.buildRule(cur, rules);

        }
      });
    },
    // 数据变更时 处理逻辑显示相关数据
    logicShowHandle(value, field, item) {
      seqNo = this.formConfCopy.startSeqNo || 0;
      // 值被包装过 需要取出原始值
      const { logicShowRule } = this.formConfCopy;
      if (!logicShowRule) {
        return;
      }
      // 找到该问题需要触发显示的问题 判断逻辑是否成立
      const rules = _.get(logicShowRule, field);
      if (rules && Array.isArray(rules)) {
        rules.forEach((r) => {
          // 成立让该对应的问题显示出来
          const flag = evalExpression(this.formModel, r.logicExpression);
          if (flag) {
            // 显示加上值必填等校验
            let triggerFormItem =
              this.formConfCopy.fields[this.fieldIdIndex[r.triggerFormItemId]];
            // 重新渲染组件 不然必填红点不显示
            if (triggerFormItem) {
              triggerFormItem.key = new Date().getTime();
              this.buildRule(triggerFormItem, this.formRules);
              // 设置默认值
              this.$set(
                this.formModel,
                r.triggerFormItemId,
                triggerFormItem.config.defaultValue
              );
            }
            // 防止问卷重新渲染 display被刷新
            this.logicTriggerItemList.push(r.triggerFormItemId);
            // let triggerEle = document.querySelector(
            //   `div[cid="${r.triggerFormItemId}"]`
            // );
            // if (triggerEle) {
              this.formConfCopy.fields[this.fieldIdIndex[r.triggerFormItemId]].config.isShow=true
              // triggerEle.style.display = "";
            // }
          } else {
            _.remove(
              this.logicTriggerItemList,
              (n) => n === r.triggerFormItemId
            );

            // 移除问卷的必填校验
            let triggerFormItem =
              this.formConfCopy.fields[this.fieldIdIndex[r.triggerFormItemId]];
            if (triggerFormItem) {
              this.removeRule(triggerFormItem);
            }
            // 移除已经填写的值
            delete this.formModel[r.triggerFormItemId];
            let triggerEle = document.querySelector(
              `div[cid="${r.triggerFormItemId}"]`
            );
            if (triggerEle) {
              this.formConfCopy.fields[this.fieldIdIndex[r.triggerFormItemId]].config.isShow=false
              // triggerEle.style.display = "none";
            }

          }
        });
      }
    },

    logicShowHandle2() {
      // 值被包装过 需要取出原始值
      const { logicShowRule } = this.formConfCopy;
      if (!logicShowRule) {
        return;
      }
      this.formConfCopy.fields.forEach(item => {
        if(!item.config.required){
          const rules = _.get(logicShowRule, item.vModel);

          if (rules && Array.isArray(rules)) {
            rules.forEach((r) => {
              // 成立让该对应的问题显示出来
              const flag = evalExpression(this.formModel, r.logicExpression);

                _.remove(
                  this.logicTriggerItemList,
                  (n) => n === r.triggerFormItemId
                );

                // 移除问卷的必填校验
                let triggerFormItem =
                  this.formConfCopy.fields[this.fieldIdIndex[r.triggerFormItemId]];
                if (triggerFormItem) {
                  this.removeRule(triggerFormItem);
                }
                // 移除已经填写的值
                delete this.formModel[r.triggerFormItemId];
                this.formConfCopy.fields[this.fieldIdIndex[r.triggerFormItemId]].config.isShow=false


            });
          }
        }

      })
    },
    handleDialogClose(){
      seqNo=this.formConfCopy.startSeqNo || 0
      this.dialogVisible = false
    },
    beforeSubmitForm: throttle(3000, true, function () {
      // 构建问卷校验规则
      this.buildRules(this.formConfCopy.fields, this.formRules)
      seqNo =this.formConfCopy.startSeqNo || 0
      this.$nextTick(() => {
        this.$refs[this.formConf.formRef].validate((valid) => {
        if (this.$store.getters["form/hasUploading"]) {
          this.$message.warning('有正在上传中的文件，请等待上传完成后提交')
          return false
        }
        if (valid) {
          if(!this.formConf.from){
            this.dialogVisible = true
          }else{
            //开始loading 1s后关闭
            this.btnLoading = true;
            setTimeout(() => {
              this.btnLoading = false;
            }, 1000);
            // 触发submit事件
            // this.$emit("submit", {submitPhoneNumber:this.formConf.submitPhoneNumber, formModel: this.formModel ,accessTime:formatDate(this.accessTime, "YYYY-mm-dd HH:MM:SS")});
          }

          return true;
        }else{
          setTimeout(() => {
            const isError = document.getElementsByClassName("is-error");
            isError[0].querySelector("input")?.focus();
          }, 100);
          return false;
        }
      });
      })

    }),
    submitForm: throttle(3000, true, function () {
      seqNo =this.formConfCopy.startSeqNo || 0
        //开始loading 1s后关闭
        this.btnLoading = true;
        setTimeout(() => {
          this.btnLoading = false;
        }, 1000);
        // 触发submit事件
        this.$emit("submit", {submitPhoneNumber:this.formConf.submitPhoneNumber, formModel: this.formModel ,accessTime:formatDate(this.accessTime, "YYYY-mm-dd HH:MM:SS")});
        if(!this.formConf.from){
            this.dialogVisible = false
        }
    }),
    /**
     *  问卷发生值变化
     * @param value 值
     * @param field 字段名
     * @param item  发生改变问卷组件对象
     */
    onInputChange(value, field, item) {
      this.$nextTick(item=>{
        this.$emit("on-change", field, value, this.models);
        this.logicShowHandle(value, field, item);
        //临时存储数据到本地 下次进入可以选择回显
        this.tempSaveFormData();
      })

    },
    /**
     * 分页下一页
     */
    nextPage(page) {
      this.switchPage("next", page);
    },

    /**
     * 分页上一页
     */
    prevPage(page) {
      this.switchPage("prev", page);
    },
    /**
     * 切换页
     */
    switchPage(eventName, page) {
      // this.formConfCopy.fields.forEach(item => {
      //     this.onInputChange(this.formModel[item.vModel], item.vModel, item)
      //     // this.onInputChange(this.formModel[this.formConfCopy.fields[this.indexActive].vModel], this.formConfCopy.fields[this.indexActive].vModel, this.formConfCopy.fields[this.indexActive])
      //   })
      this.$refs[this.formConf.formRef].validate((valid) => {
        if (!valid) {
          setTimeout(() => {
            const isError = document.getElementsByClassName("is-error");
            // isError[0].querySelector("input").focus();
          }, 100);
          return false;
        }
        this.$emit(eventName, {
          page,
          startSeqNo: this.formConfCopy.startSeqNo,
          endSeqNo: seqNo,
          formModel: this.formModel,
        });

        return true;
      });
    },
    // 字段是否能显示
    isFieldShow(item) {

      //不是逻辑显示字段
      if (!item.logicShowField) {
        return "";
      }
      // 问卷被重新渲染 控制逻辑显示隐藏
      const triggerShow =
        _.indexOf(this.logicTriggerItemList, item.vModel) > -1;
      //  或者已经被触发显示了
      this.formConfCopy.fields[this.fieldIdIndex[item.vModel]].config.isShow=triggerShow ? true : false
      // return triggerShow ? "" : "display:none";
    },
    isFieldShow2(item) {
        //不是逻辑显示字段
        if (!item.logicShowField) {
          return "";
        }
        // 问卷被重新渲染 控制逻辑显示隐藏
        const triggerShow =
          _.indexOf(this.logicTriggerItemList, item.vModel) > -1;
        return triggerShow ? "" : "display:none";
    },
    getSeqNo(index, item) {
      console.log(index,'index----')
      //是否开启显示标题
      if (
        !this.formConfCopy.theme ||
        this.formConfCopy.theme.showNumber !== true
      ) {
        return null;
      }
      // 处于显示状态并且组件不是辅助显示类型
      // (!item.logicShowField || item.config.isShow)
      if ( !this.isFieldShow2(item) && item.displayType == false) {
        if(item.typeId != 'DIVIDER' && item.typeId != 'PAGINATION'  && item.typeId != 'RANDOM_NUMBER' && item.typeId != 'SLIDER'){
          seqNo++;
        }

      }
      return seqNo;
    },

    /**
     * OCR识别完成之后 把数据填充到问卷内
     * @param val
     */
    handleOcrSuccess(val) {
      Object.keys(val).forEach((key) => {
        this.$set(this.formModel, key, val[key]);
        //更改组件key 让组件重新渲染 不然数据不会显示到问卷
        let item = this.formConfCopy.fields[this.fieldIdIndex[key]];
        item.key = new Date() + key;
      });
    },
    /**
     * 临时存储到localstore
     */
    tempSaveFormData: throttle(430, true, function () {
      // 是否打开临时存储选项
      if (this.formConf.setting && this.formConf.setting.saveNotSubmitStatus) {
        saveFormData(this.formModel, this.formConf.formKey);
      }
    }),
  },
};
</script>

<style lang="scss" scoped>
.submit-btn-form-item {
  text-align: center;
}
</style>
